home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / CUGUK / APPLICAT / C034.ZIP / DBQDIO.C < prev    next >
Text File  |  2010-11-01  |  6KB  |  252 lines

  1. /* CHARIO.C        Character-oriented file I/O
  2.  
  3.     Written 1980 by Scott W. Layson
  4.     This code is in the public domain.
  5.  
  6. These routines deal with reading and writing large blocks of
  7. characters, when they do not fit neatly in sectors.  At the moment,
  8. only sequential output is supported; input is fully random.
  9.  
  10. NGT added support to allow random output. Position first using
  11. 1) cread - cwrite will write after record read.
  12. 2) cseek - cwrite will write at position seeked.
  13.  
  14. cflush is automatic on subsequent read, seek or close.
  15.  
  16.  
  17. Integrity of isect is not yet tested, also RELATIVE cseek is not
  18. yet tested. */
  19.  
  20. /* #define DEBUG */
  21.  
  22. #define TRUE (-1)
  23. #define FALSE 0
  24. #define NULL 0
  25.  
  26.  
  27. /* i/o buffer */
  28. struct iobuf {
  29.     int fd;
  30.     int isect;            /* currently buffered sector */
  31.     int nextc;            /* index of next char in buffer */
  32.     int lastop;            /* last operation was */
  33.     char buff [128];
  34.     };
  35.  
  36. /* seek opcodes */
  37. #define ABSOLUTE    0
  38. #define RELATIVE    1
  39.  
  40. #define INPUT        0
  41. #define OUTPUT        1
  42. #define UPDATE        2
  43.  
  44. #define WASWRITE    0
  45. #define WASFLUSH    1
  46. #define WASREAD        2
  47. #define WASSEEK        3
  48. #define WASOPEN        4
  49.  
  50. copen (buf, fname)            /* open a file for char input */
  51.     struct iobuf *buf;
  52.     char *fname;
  53. {
  54.     buf->fd = open (fname, UPDATE);
  55.     if (buf->fd == -1) return (-1);
  56.     read (buf->fd, &buf->buff, 1);
  57.     buf->isect = 0;
  58.     buf->nextc = 0;
  59.     buf->lastop = WASOPEN;
  60.     return (buf);
  61.     }
  62.  
  63.  
  64. ccreat (buf, fname)            /* create a file for char output */
  65.     struct iobuf *buf;
  66.     char *fname;
  67. {
  68.     buf->fd = creat (fname);
  69.     if (buf->fd == -1) return (-1);
  70.     buf->isect = 0;
  71.     buf->nextc = 0;
  72.     buf->lastop = WASOPEN;
  73.     return (buf);
  74.     }
  75.  
  76.  
  77. cclose (buf)                /* close the file assoc. with buf */
  78.     struct iobuf *buf;
  79. {
  80.     if (buf->lastop == WASWRITE) cflush(buf);    /* NGT */
  81.     close (buf->fd);
  82.     }
  83.  
  84.  
  85. cseek (buf, nbytes, code)    /* seek to a character (input only!) */
  86.     struct iobuf *buf;
  87.     unsigned nbytes, code;
  88. {
  89.     int newsect;
  90.  
  91. #ifdef DEBUG
  92.     printf("Cseek - address = %d, code = %d, isect = %d, tell = %d\n",
  93.             nbytes,code,buf->isect,tell(buf->fd));
  94. #endif
  95.  
  96.     if (buf < 0) return (-1);
  97.     if (buf->lastop == WASWRITE) cflush(buf);    /* NGT */
  98.     if (code == RELATIVE) nbytes += buf->isect * 128 + buf->nextc;
  99.     newsect = nbytes / 128;
  100.     if (newsect != buf->isect
  101.         && (seek (buf->fd, newsect, ABSOLUTE) == -1
  102.            || read (buf->fd, &buf->buff, 1) == -1)) return (-1);
  103.     buf->nextc = nbytes % 128;
  104.     buf->isect = newsect;
  105.     buf->lastop = WASSEEK;
  106.     return (nbytes);
  107.     }
  108.  
  109. ctell (buf)        /* tell where we are in characters */
  110.     struct iobuf *buf;
  111. {
  112.     unsigned nbytes;
  113.  
  114.     if (buf < 0) return (-1);
  115.     nbytes = buf->isect * 128 + buf->nextc;
  116.     return (nbytes);
  117.     }
  118.  
  119.  
  120. cread (buf, dest, nbytes)    /* read some bytes into dest */
  121.     struct iobuf *buf;
  122.     char *dest;
  123.     unsigned nbytes;
  124. {
  125.     int navail, nsects, nleft, nread1, nread2;
  126.  
  127.     if (buf < 0) return (-1);
  128.     if (buf->lastop == WASWRITE) cflush(buf);    /* NGT */
  129.     navail = umin (nbytes, 128 - buf->nextc);
  130.     movmem (&buf->buff[buf->nextc], dest, navail);
  131.     nbytes -= navail;
  132.     buf->lastop = WASREAD;
  133.     buf->nextc += navail;
  134.     dest += navail;
  135.     nsects = nbytes / 128;
  136.     if (nsects) {
  137.         nread1 = read (buf->fd, dest, nsects);
  138.         if (nread1 == -1) return (navail);
  139.         buf->isect += nread1;
  140.         if (nread1 < nsects) return (navail + nread1 * 128);
  141.         dest += nread1 * 128;
  142.         }
  143.     else nread1 = 0;
  144.     if (buf->nextc == 128) {
  145.         nread2 = read (buf->fd, &buf->buff, 1);
  146.         if (nread2 == -1) return (navail);
  147.         ++(buf->isect);
  148.         buf->nextc = 0;
  149.         if (nread2 < 1) return (navail + nread1 * 128);
  150.         }
  151.     nleft = nbytes % 128;
  152.     movmem (&buf->buff, dest, nleft);
  153.     buf->nextc += nleft;
  154.     return (navail + nbytes);
  155.     }
  156.  
  157.  
  158. cwrite (buf, source, nbytes)    /* write some bytes from source */
  159.     struct iobuf *buf;
  160.     char *source;
  161.     unsigned nbytes;
  162. {
  163.     unsigned nleft, nfill, nsects;
  164.     int skpnt;
  165. #ifdef DEBUG
  166.     int rsects;
  167.     printf("Bytes to write = %d\n",nbytes);
  168. #endif
  169.     if (buf < 0) return (-1);
  170.     if (buf->lastop != WASWRITE) {
  171.             skpnt = buf->isect;
  172.             if (skpnt < 0) skpnt = 0;
  173. #ifdef DEBUG
  174.     printf("cwrite - skpnt = %d\n",skpnt);
  175. #endif
  176.             seek(buf->fd,skpnt,ABSOLUTE);
  177.         }
  178.     nfill = 0;
  179.     if (buf->nextc) {
  180.         nfill = umin (nbytes, 128 - buf->nextc);
  181.         movmem (source, &buf->buff[buf->nextc], nfill);
  182.         buf->nextc += nfill;
  183.         nbytes -= nfill;
  184.         source += nfill;
  185.         }
  186.     if (buf->nextc == 128) {
  187.         ++(buf->isect);
  188.         buf->nextc = 0;
  189.         if (write (buf->fd, &buf->buff, 1) < 1) return (-1);
  190.         }
  191.     nsects = nbytes / 128;
  192. #ifdef DEBUG
  193.     printf("Sectors = %d\n",nsects);
  194.     if (nsects) {
  195.         rsects = write (buf->fd, source, nsects);
  196.         printf("Written = %d\n",rsects);
  197.         if (nsects != rsects) {
  198.         printf("Write error: %s \n",errmsg(errno()));
  199.             return (-1);
  200.         }
  201.     }
  202. #else
  203.     if (nsects  &&  write (buf->fd, source, nsects) < nsects)
  204.         return (-1);
  205. #endif
  206.     buf->isect += nsects;
  207.     nbytes %= 128;
  208.     if (nbytes) {
  209.         if (read(buf->fd,&buf->buff,1) == 1)
  210.             seek(buf->fd,-1,RELATIVE);
  211.         movmem (source + nsects * 128, &buf->buff, nbytes);
  212.         buf->nextc += nbytes;
  213.         }
  214.     buf->lastop = WASWRITE;
  215. #ifdef DEBUG
  216.     printf("Bytes written = %d\n",nsects * 128 + nbytes + nfill);
  217. #endif
  218.     return (nsects * 128 + nbytes + nfill);
  219.     }
  220.  
  221.  
  222. cflush (buf)                /* flush an output buffer */
  223.     struct iobuf *buf;
  224. {
  225.     if (buf->nextc  &&  write (buf->fd, &buf->buff, 1) < 1)
  226.         return (-1);
  227.  
  228. #ifdef DEBUG
  229.     printf("cflush - nextc = %d\n",buf->nextc);
  230. #endif
  231.  
  232.     buf->lastop = WASFLUSH;
  233.     return (1);
  234.     }
  235.  
  236.  
  237. umin (a, b)                /* unsigned min */
  238.     unsigned a, b;
  239. {
  240.     return ((a < b) ? a : b);
  241.     }
  242.  
  243.  
  244. /* End of CHARIO.C  --  Character oriented file I/O */
  245. signed min */
  246.     unsigned a, b;
  247. {
  248.     return ((a < b) ? a : b);
  249.     }
  250.  
  251.  
  252. /* End of CHARIO.C  --  Character oriented file I/O */